import { RedisConfig } from "../config/RedisConfig";
import { RetCodeDefine } from "../config/RetCodeDefine";
import { Logger } from "../engine/utils/Logger";
import { RedisClient } from "../engine/utils/RedisClient";
import { RedisManager } from "../engine/utils/RedisManager";
import { UserSysInfo } from "./UserSysInfo";
import DateUtil from "../engine/utils/DateUtil";
import { ProtoUtils } from "../engine/socketserver/protocol/ProtoUtils";
import { ProtoConfig } from "../engine/socketserver/protocol/ProtoConfig";
import { ZoneModel } from "./ZoneModel";
import { Config } from "../config/Config";

export class UserModel {

    private static Redis_Key = {
        users: "users",
        user_servers: "user_servers",
    }

    public static onlyId: number = 1;

    public userId: number; //服务器直接连接过来会返回空
    public userName: string; //账号
    public pass: string; //密码
    public createTime: number; //注册时间
    public lastLoginIp: string;     //最后登录Ip
    public lastLoginTime: number;   //最后登录时间
    public sysInfo: UserSysInfo;    //系统信息

    public token: string; //token
    public serverIdList: Array<number> = [];

    //初始user唯一Id
    public static async initOnlyId() {
        let redis: RedisClient = RedisManager.instance.getRedis(RedisConfig.Database_Index.Users);
        this.onlyId = await redis.hlenPromise(this.Redis_Key.users) + 1;
        Logger.log("initOnlyId==", this.onlyId)
    }

    //redis数据转换为对象
    private static redis2User(obj: object, sysInfoPack: any): UserModel {
        let user: UserModel = new UserModel();
        user.userId = obj["userId"];
        user.userName = obj["userName"];
        user.pass = obj["pass"];
        user.createTime = obj["createTime"];
        user.lastLoginIp = obj["lastLoginIp"];
        user.lastLoginTime = obj["lastLoginTime"]
        user.sysInfo = UserSysInfo.proto2SysInfo(sysInfoPack);
        user.token = obj["token"];
        user.serverIdList = obj["serverIdList"];
        return user;
    }

    //根据用户名从redis拿到用户信息
    public static async getUserFromRedis(userName: string) {
        let redis: RedisClient = RedisManager.instance.getRedis(RedisConfig.Database_Index.Users);
        let obj = await redis.hgetPromise(this.Redis_Key.users, userName);
        return obj;
    }

    //注册
    public static async register(userName: string, pass: string): Promise<number> {
        let ret: number = RetCodeDefine.LoginError_NoUser;
        let obj = await this.getUserFromRedis(userName);
        if (!obj) {
            let user: UserModel = new UserModel();
            user.userId = this.onlyId;
            this.onlyId++;
            user.userName = userName;
            user.pass = pass;
            user.createTime = DateUtil.now();
            user.toUsersRedis();
            ret = RetCodeDefine.OK;
        } else {
            ret = RetCodeDefine.RegisterError_HadUser;
        }
        return ret;
    }

    //登录
    public static async login(userName: string, pass: string, sysInfoPack: any, loginType: number) {
        let ret: number = RetCodeDefine.LoginError_NoUser;
        let data = await this.getUserFromRedis(userName);
        let user: UserModel;
        if (!data) {
            ret = RetCodeDefine.LoginError_NoUser;
        } else {
            let obj: object = JSON.parse(data);
            if (loginType == 1) {   //密码登录
                if (obj["pass"] == pass) {
                    ret = RetCodeDefine.OK;
                    user = this.redis2User(obj, sysInfoPack);
                } else {
                    Logger.log("登录密码错误", obj["pass"], pass, obj["pass"] == pass)
                    ret = RetCodeDefine.LoginError_NoPass;
                }
            } else if (loginType == 2) { //token登录
                if (obj["token"] == pass) {
                    ret = RetCodeDefine.OK;
                    user = this.redis2User(obj, sysInfoPack);
                } else {
                    Logger.log("登录token错误", obj["token"], pass, obj["token"] == pass)
                    ret = RetCodeDefine.LoginError_NoPass;
                }
            }
        }
        let resultObj: object = {
            "ret": ret,
            "user": user
        }
        Logger.log("login====", data, resultObj)
        return resultObj
    }


    public toProto() {
        let respPack = ProtoUtils.Create(ProtoConfig.struct_user_info);
        respPack.setUserid(this.userId);
        respPack.setUsername(this.userName);
        respPack.setCreatetime(this.createTime);
        respPack.setLastlogintime(this.lastLoginTime);
        respPack.setLastloginip(this.lastLoginIp);
        respPack.setToken(this.token);
        return respPack;
    }

    //存储用户信息到users;
    public toUsersRedis() {
        let redis: RedisClient = RedisManager.instance.getRedis(RedisConfig.Database_Index.Users);
        if(Config.serverType == Config.ServerType_List.GameServer){
            if(!this.serverIdList){
                this.serverIdList = [];
            }
            this.serverIdList.push(ZoneModel.nowZone.server_id);
        }
        redis.hsetPromise(UserModel.Redis_Key.users, this.userName, JSON.stringify(this));
    }

    // public toUserServerListRedis() {
    //     let redis: RedisClient = RedisManager.instance.getRedis(RedisConfig.Database_Index.Users);
    //     let key: string = this.userName + "_" + ZoneModel.nowZone.server_id
    //     redis.hsetPromise(UserModel.Redis_Key.user_servers, key, JSON.stringify(this));
    // }

    public static test() {
        let user: UserModel = new UserModel();
        user.userId = 1;
        user.userName = "abcd";
        user.pass = "666666";
        user.sysInfo = new UserSysInfo();
        Logger.log("test=-=====", JSON.stringify(user))
        let redis: RedisClient = RedisManager.instance.getRedis(RedisConfig.Database_Index.Users);
        redis.hsetPromise(this.Redis_Key.users, user.userName, JSON.stringify(user));
    }
}